﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http.Json;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json.Nodes;
using System.Threading.Tasks;

namespace Hong.Pan
{
    internal class Https
    {
        //http请求客户端
        static HttpClient client = new HttpClient();
        //简单的下载客户端
        static HttpClient[] downClient = new HttpClient[5];

        /// <summary>
        /// get请求返回json数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<JsonNode?> Json(string url)
        {
            //HttpClient client = new HttpClient();
            Debug.WriteLine(url);
            JsonNode? jn = null;
            try
            {
                jn = await client.GetFromJsonAsync<JsonNode>(url);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            //JsonNode? jn = JsonNode.Parse(rep);
            if (jn != null)
            {
                if (jn["errno"]?.GetValue<int>() != 0)
                {
                    Debug.WriteLine(jn);
                }
            }
            return jn;
        }

        /// <summary>
        /// get请求返回string数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<HttpResponseMessage?> GetStringAsync(string url, string? UserAgent)
        {
            Debug.WriteLine(url);
            if (UserAgent != null)
            {
                client.DefaultRequestHeaders.Clear();
                //client.DefaultRequestHeaders.Add("Host", "pan.baidu.com");
                client.DefaultRequestHeaders.Add("UserAgent", UrlEncoder.Default.Encode(UserAgent));
            }
            try
            {
                var res = await client.GetAsync(url);
                return res;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            return null;
        }

        /// <summary>
        /// post请求返回数据
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httpContent"></param>
        /// <returns></returns>
        public static async Task<JsonNode?> PostJson(string url, HttpContent httpContent)
        {
            //HttpClient client = new HttpClient();
            Debug.WriteLine(url);
            JsonNode? jn = null;
            var response = await client.PostAsync(url, httpContent);
            try
            {
                if (url.IndexOf("d.pcs.baidu.com") > 0) //上传数据时编码返回时utf8 导致不认识了
                {
                    jn = JsonNode.Parse(response.Content.ReadAsStream());
                }
                else
                {
                    jn = await response.Content.ReadFromJsonAsync<JsonNode>();
                }
                //JsonNode? jn = JsonNode.Parse(rep);
                if (jn != null)
                {
                    if (jn["errno"]?.GetValue<int>() != 0)
                    {
                        Debug.WriteLine(jn);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            return jn;
        }

        /// <summary>
        /// post请求返回数据 编码返回ut8不能正常解析
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httpContent"></param>
        /// <returns></returns>
        public static async Task<JsonNode?> PostJsonUtf8(string url, HttpContent httpContent)
        {
            //HttpClient client = new HttpClient();
            Debug.WriteLine(url);
            JsonNode? jn = null;
            var response = await client.PostAsync(url, httpContent);
            try
            {
                jn = JsonNode.Parse(response.Content.ReadAsStream());
                //JsonNode? jn = JsonNode.Parse(rep);
                if (jn != null)
                {
                    if (jn["errno"]?.GetValue<int>() != 0)
                    {
                        Debug.WriteLine(jn);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            return jn;
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<int> DownloadFile(string url, string localpath, Action<long>? callback = null)
        {
            Debug.WriteLine(url);
            if (downClient[0] == null)
            {
                HttpClientHandler handler = new HttpClientHandler();
                handler.AllowAutoRedirect = true;
                downClient[0] = new HttpClient(handler);
            }
            Stream? stream = null;
            try
            {
                var response = await client.GetAsync(url);
                if (response.Headers.Location != null)
                {
                    stream = await downClient[0].GetStreamAsync(response.Headers.Location.OriginalString);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            if (stream != null)
            {
                using (var fstream = File.Open(localpath, FileMode.OpenOrCreate))
                {
                    var tk = stream.CopyToAsync(fstream);
                    if (callback != null)
                    {
                        while (!tk.Wait(500))
                        {
                            //Debug.WriteLine($"stream Position:{fstream.Position}");
                            callback(fstream.Position);
                        }
                    }
                    else
                    {
                        tk.Wait();
                    }
                }
            }
            return 0;
        }
    }
}
